--  Voorbeeld 1 (RAM)
-- Dit programma beschrijft een RAM 
-- met een apart lees en schrijf adres. 
-- Er wordt nu gebruik gemaakt van het Block RAM 
library IEEE; 
use IEEE.STD_LOGIC_1164.ALL; 
use IEEE.NUMERIC_STD.ALL;
use ieee.std_logic_textio.all;
use std.textio.all;
 
entity ram_idarray is 
	Port ( Clk : in std_logic; 
		Write_En : in std_logic; 
		Write_ADDR : in std_logic_vector(7 downto 0); 
		Read_ADDR : in std_logic_vector(7 downto 0); 
		Write_DATA : in std_logic_vector(5 downto 0); 
		Read_DATA : out std_logic_vector(5 downto 0)); 
end ram_idarray; 

architecture RTL of ram_idarray is 
	type RAM_TYPE is array (255 downto 0) of Std_logic_vector (5 downto 0);

	impure function leesfile(filenaam:in string) return ram_type is
	file datafile : text open read_mode is filenaam;
	variable l : line;
	variable RAMV: RAM_TYPE;

	begin

		for i in 0 to 255 loop
			readline(datafile,l);
			read(l,RAMV(i));
		end loop;
		
		file_close(datafile);
		return RAMV;
	end function;

	signal RAM: RAM_TYPE := leesfile("RAM_idarray.txt");

	

	signal RD_ADDR_REG : Std_logic_vector (7 downto 0); 
	begin 
		process( CLK) 
		begin 
			if Rising_edge (Clk) then 
				if Write_En = '1' then    -- nu schrijven 
					RAM(To_integer(Unsigned( Write_ADDR))) <=  Write_DATA ;  
					-- eerst verplicht schrijven 
				end if ; 
			RD_ADDR_REG <=  Read_ADDR ;   
			-- verplicht voor Block RAM 
		end if; 
		end process; 
   Read_DATA  <= RAM (To_integer(Unsigned( RD_ADDR_REG))); 
	-- zorgt ervoor dat er eerst geschreven wordt voor het lezen 
	-- Deze RAM module komt nu in het Block RAM 
	-- Indien er geen gebruik gemaakt wordt van het signal RD_ADDR-REG maar alleen 
	-- van Read_ADDR dan wordt automatisch voor distributed RAM gekozen. 
	-- Dit kost dus veel hardware (LUT's)in dit geval zijn dat 853 LUT's. 
	--Read_DATA  <= RAM (To_integer(Unsigned( Read_ADDR))); -- distributed RAM 
end RTL;

--  Voorbeeld 1 (RAM)
-- Dit programma beschrijft een RAM 
-- met een apart lees en schrijf adres. 
-- Er wordt nu gebruik gemaakt van het Block RAM 
library IEEE; 
use IEEE.STD_LOGIC_1164.ALL; 
use IEEE.NUMERIC_STD.ALL;
use ieee.std_logic_textio.all;
use std.textio.all;
 
entity ram_sprite is 
	Port ( Clk : in std_logic; 
		Write_En : in std_logic; 
		Write_ADDR : in std_logic_vector(11 downto 0); 
		Read_ADDR : in std_logic_vector(11 downto 0); 
		Write_DATA : in std_logic_vector(2 downto 0); 
		Read_DATA : out std_logic_vector(2 downto 0));
end ram_sprite; 

architecture RTL of ram_sprite is 

	type RAM_TYPE is array (4095 downto 0) of Std_logic_vector (2 downto 0); 
	
	impure function leesfile(filenaam:in string) return ram_type is
		file datafile : text open read_mode is filenaam;
		variable l : line;
		variable RAMV: RAM_TYPE;

		begin

			for i in 0 to 4095 loop
				readline(datafile,l);
				read(l,RAMV(i));
			end loop;
			
			file_close(datafile);
			return RAMV;
	end function;
	

	signal RAM: RAM_TYPE := leesfile("RAM_sprite.txt");

	signal RD_ADDR_REG : Std_logic_vector (11 downto 0); 
	begin 
		process( CLK) 
		begin 
			if Rising_edge (Clk) then 
				if Write_En = '1' then    -- nu schrijven 
					RAM(To_integer(Unsigned( Write_ADDR))) <=  Write_DATA ;  
					-- eerst verplicht schrijven 
				end if ; 
			RD_ADDR_REG <=  Read_ADDR ;   
			-- verplicht voor Block RAM 
		end if; 
		end process; 
   Read_DATA  <= RAM (To_integer(Unsigned( RD_ADDR_REG))); 
	-- zorgt ervoor dat er eerst geschreven wordt voor het lezen 
	-- Deze RAM module komt nu in het Block RAM 
	-- Indien er geen gebruik gemaakt wordt van het signal RD_ADDR-REG maar alleen 
	-- van Read_ADDR dan wordt automatisch voor distributed RAM gekozen. 
	-- Dit kost dus veel hardware (LUT's)in dit geval zijn dat 853 LUT's. 
	--Read_DATA  <= RAM (To_integer(Unsigned( Read_ADDR))); -- distributed RAM 
end RTL;

library IEEE; 
use IEEE.STD_LOGIC_1164.ALL; 
use IEEE.NUMERIC_STD.ALL;
 
entity ram_background is 
	Port ( Clk : in std_logic; 
		Write_En : in std_logic; 
		Write_ADDR : in std_logic_vector(16 downto 0); 
		Read_ADDR : in std_logic_vector(16 downto 0); 
		Write_DATA : in std_logic; 
		Read_DATA : out std_logic);
end ram_background; 

architecture RTL of ram_background is 
	type RAM_TYPE is array (9599 downto 0) of Std_logic; 
	signal RAM: RAM_TYPE; 
	signal RD_ADDR_REG : Std_logic_vector (16 downto 0); 
	begin 
		process( CLK) 
		begin 
			if Rising_edge (Clk) then 
				if Write_En = '1' then    -- nu schrijven 
					RAM(To_integer(Unsigned( Write_ADDR))) <=  Write_DATA ;  
					-- eerst verplicht schrijven 
				end if ; 
			RD_ADDR_REG <=  Read_ADDR ;   
			-- verplicht voor Block RAM 
		end if; 
		end process; 
   Read_DATA  <= RAM (To_integer(Unsigned( RD_ADDR_REG))); 
	-- zorgt ervoor dat er eerst geschreven wordt voor het lezen 
	-- Deze RAM module komt nu in het Block RAM 
	-- Indien er geen gebruik gemaakt wordt van het signal RD_ADDR-REG maar alleen 
	-- van Read_ADDR dan wordt automatisch voor distributed RAM gekozen. 
	-- Dit kost dus veel hardware (LUT's)in dit geval zijn dat 853 LUT's. 
	--Read_DATA  <= RAM (To_integer(Unsigned( Read_ADDR))); -- distributed RAM 
end RTL;

library IEEE; 
use IEEE.STD_LOGIC_1164.ALL; 
use IEEE.NUMERIC_STD.ALL;

package RAM_PACK is

component ram_background is 
	Port ( Clk : in std_logic; 
		Write_En : in std_logic; 
		Write_ADDR : in std_logic_vector(16 downto 0); 
		Read_ADDR : in std_logic_vector(16 downto 0); 
		Write_DATA : in std_logic; 
		Read_DATA : out std_logic);
end component; 

component ram_idarray is 
	Port ( Clk : in std_logic; 
		Write_En : in std_logic; 
		Write_ADDR : in std_logic_vector(7 downto 0); 
		Read_ADDR : in std_logic_vector(7 downto 0); 
		Write_DATA : in std_logic_vector(5 downto 0); 
		Read_DATA : out std_logic_vector(5 downto 0)); 
end component;

component ram_sprite is 
	Port ( Clk : in std_logic; 
		Write_En : in std_logic; 
		Write_ADDR : in std_logic_vector(11 downto 0); 
		Read_ADDR : in std_logic_vector(11 downto 0); 
		Write_DATA : in std_logic_vector(2 downto 0); 
		Read_DATA : out std_logic_vector(2 downto 0));
end component; 

end RAM_PACK;